#include <iostream>

using std::cout;
using std::endl;

//模板本质上是代码生成器
//函数模板  -->  模板函数
//       模板参数推导(模板实例化)
//都是由编译器来进行的，在编译时完成该操作
//
//
//class 代表的是声明类型参数
//
//<>   模板参数列表
template <class T>
//template <typename T>
T add(T x, T y)
{
    cout << "T add(T,T)" << endl;
    return x + y;
}

template <class T1, class T2>
T1 add(T1 x, T2 y)
{
    return x + y;
}

//函数模板之间可以进行重载

//普通函数与函数模板之间也可以进行重载
//而且普通函数会优先与函数模板调用
#if 1
int add(int x, int y)
{
    cout << "int add(int,int)" << endl;
    return x + y;
}

#endif

class A
{};

int main()
{
    int i1 = 1, i2 = 2;
    double d1 = 1.1, d2 = 2.2;
    float f1 = 3.3f, f2 = 4.4f;

    //根据实际调用时，传递的参数类型来自动进行推导
    //在实际调用时，没有加上模板参数列表称为隐式实例化
    cout << "add(i1, i2):" << add(i1, i2) << endl;
    cout << "add(d1, d2):" << add(d1, d2) << endl;
    cout << "add(f1, f2):" << add(f1, f2) << endl;
    //在实际调用时，加上模板参数列表的，称为显式实例化
    cout << "add(i1, d1):" << add<double>(i1, d1) << endl;

    return 0;
}

